题目链接: https://ac.nowcoder.com/acm/problem/15815?&headNav=acm
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| #include<bits/stdc++.h> using namespace std; typedef long long ll; const int INF=0x3f3f3f3f; const int MAX_N=1e6+5; const int mod=100003; int n; int a[MAX_N]; stack<int> sta; int l[MAX_N]; int r[MAX_N]; int main(){
while(scanf("%d",&n)!=EOF) { ll ans=0; for(int i=1;i<=n;i++) { scanf("%d",a+i); } for(int i=1;i<=n;i++) { while(sta.size()&&a[sta.top()]>a[i]) sta.pop(); l[i]=sta.empty()?1:sta.top()+1; sta.push(i); } while(sta.size()) sta.pop(); for(int i=n;i>=1;i--) { while(sta.size()&&a[sta.top()]>=a[i]) sta.pop(); r[i]=sta.empty()?n:sta.top()-1; sta.push(i); } while(sta.size()) sta.pop(); for(int i=1;i<=n;i++) { ans-=(ll)a[i]*((ll)(r[i]-i+1)*(ll)(i-l[i]+1)-1); } for(int i=1;i<=n;i++) { while(sta.size()&&a[sta.top()]<a[i]) sta.pop(); l[i]=sta.empty()?1:sta.top()+1; sta.push(i); } while(sta.size()) sta.pop(); for(int i=n;i>=1;i--) { while(sta.size()&&a[sta.top()]<=a[i]) sta.pop(); r[i]=sta.empty()?n:sta.top()-1; sta.push(i); } while(sta.size()) sta.pop(); for(int i=1;i<=n;i++) { ans+=(ll)a[i]*((ll)(r[i]-i+1)*(ll)(i-l[i]+1)-1); } printf("%lld\n",ans); }
return 0; }
|
其实可以两次循环就做完了,一次循环就能求出L和R。进栈的时候可以求出L[i],出栈的时候可以求出sta.top的R;